package com.alibaba.algo.components.yapi.service.impl;

import java.io.IOException;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import javax.annotation.PostConstruct;

import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;

import com.alibaba.algo.components.yapi.YapiDataCacheManger;
import com.alibaba.algo.components.yapi.constant.UrlConstant;
import com.alibaba.algo.components.yapi.entity.CatMenu;
import com.alibaba.algo.components.yapi.entity.InterfaceInfo;
import com.alibaba.algo.components.yapi.entity.Project;
import com.alibaba.algo.components.yapi.service.YapiOpenService;
import com.alibaba.algo.components.yapi.util.HttpClientUtils;
import com.alibaba.algo.components.yapi.vo.InterfaceRequestVO;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;

import lombok.extern.slf4j.Slf4j;

/**
 * @Description: yapi服务实现类
 * @author: malin
 * @date: 2020-12-1 11:20:31
 */
@Slf4j
@Service
public class YapiOpenServiceImpl implements YapiOpenService {
	@Value("${yapi.url}")
	private String yapiUrl;
	@Value("${yapi.token}")
	private String token;
	@Value("${yapi.auto-register}")
	private boolean autoRegister;

	@Override
	public Project get() {
		Map<String, String> params = new HashMap<String, String>();
		params.put("token", token);
		String result = HttpClientUtils.doGet(yapiUrl + UrlConstant.YAPI_PROJECT_GET, params);
		log.info("get result:{}", result);
		if (StringUtils.isEmpty(result)) {
			return null;
		}
		JSONObject resultJson = JSON.parseObject(result);
		if (resultJson == null) {
			return null;
		}
		return JSONObject.parseObject(resultJson.getString("data"), Project.class);
	}

	@Override
	public List<CatMenu> getCatMenu() {
		Map<String, String> params = new HashMap<String, String>();
		params.put("token", token);
		String result = HttpClientUtils.doGet(yapiUrl + UrlConstant.YAPI_INTERFACE_GET_CATMENU, params);
		log.info("getCatMenu result:{}", result);
		if (StringUtils.isEmpty(result)) {
			return null;
		}
		JSONObject resultJson = JSON.parseObject(result);
		if (resultJson == null) {
			return null;
		}
		return JSONObject.parseArray(resultJson.getJSONArray("data").toJSONString(), CatMenu.class);
	}

	@Override
	public Integer addCat(String desc, String name, Integer projectId) {
		Map<String, String> params = new HashMap<String, String>();
		params.put("token", token);
		params.put("desc", desc);
		params.put("name", name);
		params.put("project_id", projectId.toString());
		String result = null;
		try {
			result = HttpClientUtils.doPost(yapiUrl + UrlConstant.YAPI_INTERFACE_ADD_CAT, params);
			log.info("addCat result:{}", result);
		} catch (IOException e) {
			log.error("addCat error", e);
		}
		if (StringUtils.isEmpty(result)) {
			return null;
		}
		JSONObject resultJson = JSON.parseObject(result);
		if (resultJson == null) {
			return null;
		}
		if (resultJson.containsKey("errcode") && resultJson.getInteger("errcode") == 0) {
			CatMenu catMenu = new CatMenu();
			catMenu.setDesc(desc);
			catMenu.setName(name);
			catMenu.setId(resultJson.getJSONObject("data").getInteger("_id"));
			catMenu.setProjectId(projectId);
			YapiDataCacheManger.addCatMenu(catMenu);
			return catMenu.getId();
		}
		return null;
	}

	@Override
	public List<InterfaceInfo> list() {
		Map<String, String> params = new HashMap<String, String>();
		params.put("token", token);
		params.put("page", "1");
		params.put("limit", "1000");
		String result = HttpClientUtils.doGet(yapiUrl + UrlConstant.YAPI_INTERFACE_LIST, params, "application/json");
		log.info("list result:{}", result);
		if (StringUtils.isEmpty(result)) {
			return null;
		}
		JSONObject resultJson = JSON.parseObject(result);
		if (resultJson == null) {
			return null;
		}
		return JSONObject.parseArray(resultJson.getJSONObject("data").getJSONArray("list").toJSONString(),
				InterfaceInfo.class);
	}

	@Override
	public boolean save(InterfaceRequestVO interfaceRequestVO) {
		interfaceRequestVO.setToken(token);
		String result = null;
		try {
			String requestJson = JSON.toJSONString(interfaceRequestVO);
			log.info("save requestJson:{}", requestJson);
			result = HttpClientUtils.doPost(yapiUrl + UrlConstant.YAPI_INTERFACE_SAVE, requestJson);
			log.info("save result:{}", result);
		} catch (IOException e) {
			log.error("save error", e);
			return false;
		}
		if (StringUtils.isEmpty(result)) {
			return false;
		}
		JSONObject resultJson = JSON.parseObject(result);
		if (resultJson == null) {
			return false;
		}
		if (resultJson.containsKey("errcode") && resultJson.getInteger("errcode") == 0) {
			return true;
		}
		return false;
	}

	@PostConstruct
	public void initProject() throws IOException {
		if (autoRegister) {
			Project project = get();
			YapiDataCacheManger.setProject(project);
			log.info("initProject project:{}", JSON.toJSONString(project));
		}
	}

	/**
	 * @Description: 初始化获取yapi接口分类列表
	 * @author: malin
	 * @date: 2020-12-1 17:20:55
	 */
	@PostConstruct
	public void initCatMenu() throws IOException {
		if (autoRegister) {
			List<CatMenu> catMenuList = getCatMenu();
			if (!CollectionUtils.isEmpty(catMenuList)) {
				YapiDataCacheManger.addCatMenu(catMenuList);
			}
			log.info("catMenuList size:{}", catMenuList.size());
		}
	}

	@PostConstruct
	public void initInterface() throws IOException {
		if (autoRegister) {
			List<InterfaceInfo> list = list();
			YapiDataCacheManger.addInterfaceInfoList(list);
			log.info("initInterface InterfaceInfoList:{}", JSON.toJSONString(list));
		}
	}

	@Override
	public void initData() {
		Project project = get();
		YapiDataCacheManger.setProject(project);
		log.info("initProject project:{}", JSON.toJSONString(project));

		List<CatMenu> catMenuList = getCatMenu();
		if (!CollectionUtils.isEmpty(catMenuList)) {
			YapiDataCacheManger.addCatMenu(catMenuList);
		}
		log.info("catMenuList size:{}", catMenuList.size());

		List<InterfaceInfo> list = list();
		YapiDataCacheManger.addInterfaceInfoList(list);
		log.info("initInterface InterfaceInfoList:{}", JSON.toJSONString(list));
	}
}
